home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / LIB / UNIXLIB37B / !UnixLib37 / src / c / termcap < prev   
Text File  |  1996-11-09  |  16KB  |  952 lines

  1. /****************************************************************************
  2.  *
  3.  * $Source: /unixb/home/unixlib/source/unixlib37/src/c/RCS/termcap,v $
  4.  * $Date: 1996/11/06 22:01:41 $
  5.  * $Revision: 1.4 $
  6.  * $State: Rel $
  7.  * $Author: unixlib $
  8.  *
  9.  * $Log: termcap,v $
  10.  * Revision 1.4  1996/11/06 22:01:41  unixlib
  11.  * Yet more changes by NB, PB and SC.
  12.  *
  13.  * Revision 1.3  1996/07/21 22:12:30  unixlib
  14.  * CL_0001 Nick Burret
  15.  * Improve memory handling. Remove C++ library incompatibilities.
  16.  * Improve file stat routines.
  17.  *
  18.  * Revision 1.2  1996/05/06 09:03:13  unixlib
  19.  * Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
  20.  * Saved for 3.7a release.
  21.  *
  22.  * Revision 1.1  1996/04/19 21:26:42  simon
  23.  * Initial revision
  24.  *
  25.  ***************************************************************************/
  26.  
  27. static const char rcs_id[] = "$Id: termcap,v 1.4 1996/11/06 22:01:41 unixlib Rel $";
  28.  
  29. #include <sys/syslib.h>
  30. #include <sys/ioctl.h>
  31.  
  32. #include <stdio.h>
  33. #include <string.h>
  34. #include <ctype.h>
  35. #include <stdlib.h>
  36.  
  37. #include <termcap.h>
  38.  
  39. #define T_BUILTIN        /* builtin termcap */
  40.  
  41. static char *t_bname = "acorn0";
  42. static unsigned char *t_btenv = (unsigned char *)
  43. "av|acorn0|Acorn VDU Driver Mode 0:"
  44. ":li#32:co#80:am:cl=^L:bs:cm=^_%r%.%.:up=^K:ho=^^:bl=^G:bw:"
  45. ":ce=^W^H^E^F\\200\\200\\200\\200\\200\\200:"
  46. ":so=^W^Q^E\\200\\200\\200\\200\\200\\200\\200:"
  47. ":se=^W^Q^E\\200\\200\\200\\200\\200\\200\\200:"
  48. ":sb=^W^G^A^B\\200\\200\\200\\200\\200\\200:"
  49. ":sf=^W^G^A^C\\200\\200\\200\\200\\200\\200:"
  50. ":is=^C^F^D^O^V\\200:";
  51.  
  52. #define T_IOCTL            /* use TIOCGWINSIZ to get LI,CO */
  53.  
  54. #ifdef T_IOCTL
  55. #include <termio.h>
  56. #endif
  57.  
  58. /* #define T_TEST */
  59. /* test main() */
  60.  
  61. /* #define T_DEBUG */
  62. /* debugging output to t_debug */
  63.  
  64. #define T_FILE "/etc/termcap"    /* the database file */
  65.  
  66. static int t_tgetnam (unsigned char **, unsigned char **);
  67. static int t_tgetln (FILE *, unsigned char *);
  68. static int t_tentcp (unsigned char *);
  69. static unsigned char *t_tgetid (char *);
  70. static unsigned char t_tcoord (int, unsigned int *);
  71.  
  72. #define MAXTC 64        /* max. tc indirections */
  73.  
  74. static char __PC, *__BC, *__UP;
  75.  
  76. static char *t_tbp;
  77. static unsigned char *t_tbpstart;
  78. static int t_recurs, t_tbpspace;
  79. static unsigned char *t_tenv;
  80. short ospeed;
  81.  
  82. #ifdef T_DEBUG
  83. static FILE *t_debug;
  84. #endif
  85.  
  86. /* tgetent() */
  87.  
  88. int
  89. tgetent (char *bp, char *name)
  90. {
  91.   unsigned char *tenv, *tent, *tentbuf, tc;
  92.   unsigned char *tp1, *tp2;
  93.   char *fnam;
  94.   FILE *tfile = 0;
  95.   int nbyt, rval;
  96.  
  97. #ifdef T_DEBUG
  98.   if (!t_recurs)
  99.     {
  100.       if (!(t_debug = fopen ("t_debug", "w")))
  101.     return (-1);
  102.       setvbuf (t_debug, (char *) 0, _IONBF, BUFSIZ);
  103.     }
  104. #endif
  105.  
  106.   if (!(t_tbp = bp))
  107.     return (-1);
  108.  
  109.   if (!name)
  110. #ifdef T_BUILTIN
  111. #ifdef T_DEBUG
  112.     fputs ("tgetent(\"(null)\")\n", t_debug);
  113. #endif
  114.   name = t_bname;
  115. #else
  116.     return (-1);
  117. #endif
  118.  
  119.   fnam = T_FILE;
  120.  
  121.   if (!t_recurs)
  122.     t_tbpspace = 1024;
  123.  
  124.   if (!t_recurs)
  125.     {
  126.       char *t = getenv ("TERM");
  127.  
  128.       if (!t)
  129.     t = "";
  130.       if (!strcmp (name, t))
  131.     t_tenv = (unsigned char *) getenv ("TERMCAP");
  132.       else
  133.     t_tenv = 0;
  134.     }
  135.  
  136.   if (tenv = t_tenv)
  137.     {
  138.       if (!t_recurs && *tenv != '/')
  139.     {
  140. #ifdef T_BUILTIN
  141.     builtin:
  142. #endif
  143.  
  144.       while (isspace (*tenv))
  145.         tenv++;
  146.       tp1 = tp2 = tenv;
  147.  
  148. #ifdef T_DEBUG
  149.       fprintf (t_debug, "tgetent(\"%s\") < $TERMCAP\n", name);
  150. #endif
  151.  
  152.       while (t_tgetnam (&tp1, &tp2))
  153.         {
  154.           tc = *tp2;
  155.           *tp2 = 0;
  156.  
  157. #ifdef T_DEBUG
  158.           fprintf (t_debug, "t_tgetnam(): %s\n", (char *) tp1);
  159. #endif
  160.  
  161.           if (!strcmp ((char *) tp1, name))
  162.         {
  163.           *tp2 = tc;
  164.  
  165. #ifdef T_DEBUG
  166.           fputs ("t_tgetnam() - MATCH -\n", t_debug);
  167. #endif
  168.  
  169.           if (strlen ((char *) tenv) > t_tbpspace)
  170.             return (-1);
  171.           return (t_tentcp (tenv) ? -1 : 1);
  172.         }
  173.           else
  174.         *tp2 = tc;
  175.         }
  176.     }
  177.       else if (*tenv == '/')
  178.     {
  179.  
  180. #ifdef T_DEBUG
  181.       fprintf (t_debug, "tgetent(\"%s\") < %s\n", name, (char *) tenv);
  182. #endif
  183.  
  184.       fnam = (char *) tenv;
  185.     }
  186.     }
  187.  
  188. #ifdef T_DEBUG
  189.   if (fnam != (char *) t_tenv)
  190.     fprintf (t_debug, "tgetent(\"%s\") < /etc/termcap\n", name);
  191. #endif
  192.  
  193.   if (!(tfile = fopen (fnam, "r")))
  194. #ifdef T_BUILTIN
  195.     {
  196.       if (fnam != (char *) t_tenv && !strcmp (name, t_bname))
  197.     {
  198.       tenv = t_btenv;
  199.       goto builtin;
  200.     }
  201.       else
  202.     return (-1);
  203.     }
  204. #else
  205.     return (-1);
  206. #endif
  207.  
  208.   tent = tentbuf = (unsigned char *) malloc (1024);
  209.   /* Not enough space for malloc call.  */
  210.   if (tent == 0)
  211.     return -1;
  212.  
  213.   while (nbyt = t_tgetln (tfile, tent))
  214.     {
  215.       if (*tent != '#')
  216.     {
  217.       while (isspace (*tent))
  218.         tent++;
  219.       tp1 = tp2 = tent;
  220.       while (t_tgetnam (&tp1, &tp2))
  221.         {
  222.           tc = *tp2;
  223.           *tp2 = 0;
  224.  
  225. #ifdef T_DEBUG
  226.           fprintf (t_debug, "t_tgetnam(): %s\n", (char *) tp1);
  227. #endif
  228.  
  229.           if (!strcmp ((char *) tp1, name))
  230.         {
  231.           *tp2 = tc;
  232.  
  233. #ifdef T_DEBUG
  234.           fprintf (t_debug, "t_tgetnam() - MATCH -\n");
  235.           fprintf (t_debug, "t_tgetnam(): [%d (%d)] %s\n", nbyt, t_tbpspace, tent);
  236. #endif
  237.  
  238.           if (nbyt > t_tbpspace || nbyt < 0)
  239.             {
  240.               free ((char *) tentbuf);
  241.               return (-1);
  242.             }
  243.           if (tfile)
  244.             {
  245.               fclose (tfile);
  246.               tfile = 0;
  247.             }
  248.           rval = t_tentcp (tent);
  249.           free ((char *) tentbuf);
  250.           return (rval ? -1 : 1);
  251.         }
  252.           else
  253.         *tp2 = tc;
  254.         }
  255.     }
  256.     }
  257.  
  258.   if (tfile)
  259.     {
  260.       fclose (tfile);
  261.       tfile = 0;
  262.     }
  263.  
  264.   free ((char *) tentbuf);
  265.  
  266.   return (0);
  267. }
  268.  
  269. /* t_tgetnam() */
  270.  
  271. static int
  272. t_tgetnam (unsigned char **t1, unsigned char **t2)
  273. {
  274.   register unsigned char *tp1 = *t1, *tp2 = *t2;
  275.  
  276.   while ((*tp2 == '|') || isspace (*tp2))
  277.     tp2++;
  278.   if (*tp2 == ':')
  279.     return (0);
  280.   tp1 = tp2;
  281.   while ((*tp2 != '|') && (*tp2 != ':'))
  282.     tp2++;
  283.  
  284.   *t1 = tp1;
  285.   *t2 = tp2;
  286.   return (-1);
  287. }
  288.  
  289. /* t_tentcp() */
  290.  
  291. static int
  292. t_tentcp (unsigned char *s)
  293. {
  294.   register unsigned char *s1, *s2, *sp;
  295.   char *t_tbp_;
  296.   char *tcnam, *tcn;
  297.  
  298. #ifdef T_DEBUG
  299.   fputs ("t_tentcp()\n", t_debug);
  300. #endif
  301.  
  302.   tcnam = (char *) malloc (256);
  303.   /* Not enough space for malloc.  */
  304.   if (tcnam == 0)
  305.     return -1;
  306.  
  307.   s1 = (unsigned char *) t_tbp;
  308.   s2 = s;
  309.  
  310.   while (*s2)
  311.     {
  312.       if (*s2 == ':')        /* strips out empty capabilities :: */
  313.     {
  314.       sp = s2 + 1;
  315.       while (isspace (*sp))
  316.         sp++;
  317.       if (*sp == ':')
  318.         s2 = sp;
  319.     }
  320.       *s1++ = *s2++;
  321.     }
  322.  
  323.   *s1 = 0;
  324.  
  325.   if (!t_recurs)
  326.     {
  327.       sp = (unsigned char *) t_tbp;
  328.       while (*sp++ != ':');
  329.       t_tbpstart = sp;
  330.     }
  331.  
  332.   if (sp = t_tgetid ("tc"))
  333.     {
  334.  
  335. #ifdef T_DEBUG
  336.       fprintf (t_debug, "tgetent()# %d\n", t_recurs);
  337. #endif
  338.  
  339.       if (++t_recurs > (MAXTC - 1))
  340.     {
  341.       free (tcnam);
  342.       return (-1);
  343.     }
  344.       t_tbp_ = t_tbp;
  345.  
  346.       tcn = tcnam;
  347.       s1 = sp = sp - 2;
  348.       t_tbpspace -= (int) (s1 - (unsigned char *) t_tbp);
  349.       if (tgetent ((char *) s1, tgetstr ("tc", &tcn)) < 1)
  350.     {
  351.       free (tcnam);
  352.       return (-1);
  353.     }
  354.  
  355.       while (*sp++ != ':');
  356.       while (*s1++ = *sp++);
  357.  
  358.       t_tbp = t_tbp_;
  359.       t_recurs--;
  360.     }
  361.  
  362. #ifdef T_DEBUG
  363.   fprintf (t_debug, "tgetent(): %s\n", t_tbp);
  364. #endif
  365.  
  366.   if (!t_recurs)
  367.     {
  368.       __PC = 0;
  369.       __BC = "\b";
  370.       __UP = "\v";
  371.     }
  372.  
  373.   free (tcnam);
  374.  
  375.   return (0);
  376. }
  377.  
  378. /* t_tgetln() */
  379.  
  380. static int
  381. t_tgetln (FILE * tfile, register unsigned char *buf)
  382. {
  383.   register unsigned char *bufp;
  384.   register int nbyt;
  385.  
  386.   bufp = buf;
  387.   nbyt = 0;
  388.  
  389.   while (-1)
  390.     {
  391.       if (!fgets ((char *) bufp, t_tbpspace - nbyt, tfile))
  392.     return (nbyt);
  393.       while (*bufp++);
  394.       bufp--;
  395.       if (*--bufp != '\n')
  396.     ++bufp;
  397.       nbyt += (bufp - buf);
  398.       if (!nbyt)
  399.     continue;
  400.       if (*--bufp != '\\')
  401.     {
  402.       *++bufp = 0;
  403.       return (nbyt);
  404.     }
  405.       buf = bufp;
  406.       nbyt--;
  407.     }
  408. }
  409.  
  410. /* t_tgetid() */
  411.  
  412. static unsigned char *
  413. t_tgetid (register char *id)
  414. {
  415.   register unsigned char *bptr;
  416.   int found;
  417.  
  418.   if ((!id) || (!t_tbpstart))
  419.     return (0);
  420.  
  421.   bptr = t_tbpstart;
  422.   while (*bptr)
  423.     {
  424.       found = (((unsigned char) *id++ == *bptr++) ? \
  425.            ((unsigned char) *id == *bptr) : 0);
  426.       bptr++;
  427.       id--;
  428.       if (found)
  429.     {
  430.       if (*bptr == '@')
  431.         return (0);
  432.       else
  433.         return (bptr);
  434.     }
  435.       while ((*bptr != ':') && (*bptr != 0))
  436.     bptr++;
  437.       if (*bptr == ':')
  438.     bptr++;
  439.     }
  440.   return (0);
  441. }
  442.  
  443. /* tgetnum() */
  444.  
  445. int
  446. tgetnum (char *id)
  447. {
  448.   register unsigned char *eptr;
  449.   int rval;
  450.  
  451. #ifdef TIOCGWINSZ
  452.   if (rval = (!strncmp (id, "li", 2) ? 1 : (!strncmp (id, "co", 2) ? -1 : 0)))
  453.     {
  454.       struct winsize w[1];
  455.  
  456.       ioctl (2, TIOCGWINSZ, w);
  457.       return ((rval > 0) ? w->ws_row : w->ws_col);
  458.     }
  459. #endif
  460.  
  461.   if (!(eptr = t_tgetid (id)))
  462.     return (-1);
  463.  
  464.   if (*eptr++ != '#')
  465.     return (0);
  466.   rval = atoi ((const char *) eptr);
  467.  
  468. #ifdef T_DEBUG
  469.   fprintf (t_debug, "tgetnum(\"%s\"): %d\n", id, rval);
  470. #endif
  471.  
  472.   return (rval);
  473. }
  474.  
  475. /* tgetflag() */
  476.  
  477. int
  478. tgetflag (char *id)
  479. {
  480.   register unsigned char *idp;
  481.  
  482. #ifdef T_DEBUG
  483.   int rval;
  484.  
  485.   idp = t_tgetid (id);
  486.   rval = (idp ? ((*idp != '@') ? 1 : 0) : 0);
  487.   fprintf (t_debug, "tgetflag(\"%s\"): %d\n", id, rval);
  488.   return (rval);
  489. #else
  490.   idp = t_tgetid (id);
  491.   return (idp ? ((*idp != '@') ? 1 : 0) : 0);
  492. #endif
  493. }
  494.  
  495. /* tgetstr() */
  496.  
  497. char *
  498. tgetstr (char *id, char **area)
  499. {
  500.   register unsigned char *eptr, *aptr;
  501.   unsigned char obuf[4];
  502.   char *rval;
  503.  
  504. #ifdef T_DEBUG
  505.   fprintf (t_debug, "tgetstr(\"%s\")\n", id);
  506. #endif
  507.  
  508.   if (!(area ? *area : 0))
  509.     {
  510.       rval = 0;
  511.       goto tgetstr_ret;
  512.     }
  513.  
  514.   aptr = (unsigned char *) *area;
  515.   if (!(eptr = t_tgetid (id)))
  516.     return (0);
  517.   if (*eptr++ != '=')
  518.     {
  519.       *aptr = 0;
  520.       return (0);
  521.     }
  522.  
  523.   if ((*eptr >= '0') && (*eptr <= '9'))
  524.     {
  525.       while ((*eptr >= '0') && (*eptr <= '9'))
  526.     *aptr++ = *eptr++;
  527.       if (*eptr == '*')
  528.     *aptr++ = *eptr++;
  529.     }
  530.  
  531.   obuf[3] = 0;
  532.   while ((*eptr != ':') && (*eptr != 0))
  533.     {
  534.       switch (*eptr)
  535.     {
  536.     case '\\':
  537.       switch (*++eptr)
  538.         {
  539.         case 'E':
  540.           *aptr = 0x1b;
  541.           break;
  542.         case 'n':
  543.           *aptr = 0x0a;
  544.           break;
  545.         case 'r':
  546.           *aptr = 0x0d;
  547.           break;
  548.         case 't':
  549.           *aptr = 0x09;
  550.           break;
  551.         case 'b':
  552.           *aptr = 0x08;
  553.           break;
  554.         case 'f':
  555.           *aptr = 0x0c;
  556.           break;
  557.         case '0':
  558.         case '1':
  559.         case '2':
  560.         case '3':
  561.           obuf[0] = *eptr++;
  562.           obuf[1] = *eptr++;
  563.           obuf[2] = *eptr;
  564.           *aptr = (char) (strtol ((const char *) obuf, 0, 8) & 0xff);
  565.           break;
  566.         default:
  567.           *aptr = *eptr;
  568.         }
  569.       break;
  570.     case '^':
  571.       *aptr = ((*++eptr) & 0x1f);
  572.       break;
  573.     default:
  574.       *aptr = *eptr;
  575.       break;
  576.     }
  577.       eptr++;
  578.       aptr++;
  579.     }
  580.  
  581.   *aptr++ = 0;
  582.   rval = *area;
  583.   *area = (char *) aptr;
  584.  
  585. tgetstr_ret:
  586.  
  587. #ifdef T_DEBUG
  588.   fprintf (t_debug, "tgetstr(\"%s\"): %s\n", id, rval);
  589. #endif
  590.  
  591.   if (rval)
  592.     {
  593.       if (id[1] == 'c')
  594.     {
  595.       if (id[0] == 'b')
  596.         __BC = rval;
  597.       else if (id[0] == 'p')
  598.         __PC = *rval & 0x7f;
  599.     }
  600.       else if (id[0] == 'u' && id[1] == 'p')
  601.     __UP = rval;
  602.       else if (id[0] == 'l' && id[1] == 'e')    /* terminfo compatibility */
  603.     __BC = rval;
  604.     }
  605.  
  606.   return (rval);
  607. }
  608.  
  609. static int tg_aoff, tg_coff, tg_clev;
  610.  
  611. #define TG_revxy    0001
  612. #define TG_incxy    0002
  613. #define TG_eorxy    0004
  614. #define TG_bcdxy    0010
  615. #define TG_revcod    0020
  616. #define TG_bc        0040
  617. #define TG_up        0100
  618. #define TG_chkout    0200
  619.  
  620. /* tgoto() */
  621.  
  622. char *
  623. tgoto (char *cm, int destcol, int destline)
  624. {
  625.   static char rstr[256];
  626.   register char *cmp, *rstrp, *cp;
  627.   unsigned int f;
  628.  
  629. #define TC(f) (((f) & TG_revxy) ? destcol : destline)
  630.  
  631. #ifdef T_DEBUG
  632.   fprintf (t_debug, "tgoto(\"%s\",%d,%d): ", cm, destcol, destline);
  633.  
  634.   if (!cm)
  635.     {
  636.       putc ('\n', t_debug);
  637.       return (0);
  638.     }
  639. #else
  640.   if (!cm)
  641.     return (0);
  642. #endif
  643.  
  644.   tg_aoff = tg_coff = tg_clev = 0;
  645.   f = 0;
  646.  
  647.   cmp = cm;
  648.   rstrp = rstr;
  649.   while (*cmp)
  650.     {
  651.       if (*cmp == '%')
  652.     {
  653.       register int d;
  654.       register char *e;
  655.  
  656.       cmp++;
  657.       switch (*cmp++)
  658.         {
  659.         case 'r':
  660.           f |= TG_revxy;
  661.           break;
  662.         case 'i':
  663.           f |= TG_incxy;
  664.           break;
  665.         case 'n':
  666.           f |= TG_eorxy;
  667.           break;
  668.         case 'B':
  669.           f |= TG_bcdxy;
  670.           break;
  671.         case 'D':
  672.           f |= TG_revcod;
  673.           break;
  674.         case '>':
  675.           tg_clev = *cmp++;
  676.           tg_coff = *cmp++;
  677.           break;
  678.         case '+':
  679.           tg_aoff = *cmp++;    /* fallthru */
  680.         case '.':
  681.           f |= TG_chkout;
  682.           *rstrp++ = t_tcoord (TC (f), &f);
  683.           break;
  684.         case 'd':
  685.           d = (int) t_tcoord (TC (f), &f);
  686.           e = rstrp + 1;
  687.           if (d > 9)
  688.         e++;
  689.           if (d > 99)
  690.         e++;
  691.           rstrp = e;
  692.           *e = 0;
  693.           do
  694.         {
  695.           *--e = (d % 10) + '0';
  696.           d /= 10;
  697.         }
  698.           while (d);
  699.           break;
  700.         case '2':
  701.           d = (int) t_tcoord (TC (f), &f);
  702.           *rstrp = ' ';
  703.           if (d > 99)
  704.         *++rstrp = ' ';
  705.           e = rstrp = rstrp + 2;
  706.           *e = 0;
  707.           do
  708.         {
  709.           *--e = (d % 10) + '0';
  710.           d /= 10;
  711.         }
  712.           while (d);
  713.           break;
  714.         case '3':
  715.           d = (int) t_tcoord (TC (f), &f);
  716.           *rstrp = ' ';
  717.           *++rstrp = ' ';
  718.           e = rstrp = rstrp + 2;
  719.           *e = 0;
  720.           do
  721.         {
  722.           *--e = (d % 10) + '0';
  723.           d /= 10;
  724.         }
  725.           while (d);
  726.           break;
  727.         case '%':
  728.           *rstrp++ = '%';
  729.           break;
  730.         default:
  731.           rstrp = "OOPS";
  732.           goto tgoto_ret;
  733.           break;
  734.         }
  735.     }
  736.       else
  737.     *rstrp++ = *cmp++;
  738.     }
  739.  
  740.   if (f & TG_bc)
  741.     {
  742.       cp = __BC;
  743.       while (*rstrp = *cp)
  744.     rstrp++, cp++;
  745.     }
  746.   if (f & TG_up)
  747.     {
  748.       cp = __UP;
  749.       while (*rstrp = *cp)
  750.     rstrp++, cp++;
  751.     }
  752.  
  753.   *rstrp = 0;
  754.  
  755.   rstrp = rstr;
  756.  
  757. tgoto_ret:
  758.  
  759. #ifdef T_DEBUG
  760.   fprintf (t_debug, "%s\n", rstrp);
  761. #endif
  762.  
  763.   return (rstrp);
  764. }
  765.  
  766. /* t_tcoord() */
  767.  
  768. static unsigned char
  769. t_tcoord (register int x, unsigned int *_f)
  770. {
  771.   register unsigned int f;
  772.  
  773. t_tccalc:
  774.  
  775.   f = (*_f);
  776.  
  777.   if (x > tg_clev)
  778.     x += tg_coff;
  779.   x += tg_aoff;
  780.   if (f & TG_incxy)
  781.     x++;
  782.   if (f & TG_eorxy)
  783.     x ^= 0140;
  784.   if (f & TG_bcdxy)
  785.     x = ((x / 10) << 4) | (x % 10);
  786.   if (f & TG_revcod)
  787.     x = (x - ((x & 15) << 1));
  788.  
  789.   if (f & TG_chkout)
  790.     {
  791.       (*_f) &= (~TG_chkout);
  792.       if (!x || x == '\004' || x == '\n' || x == '\r')
  793.     {
  794.       if (f & TG_revxy)
  795.         (*_f) |= TG_bc;
  796.       else
  797.         (*_f) |= TG_up;
  798.       x++;
  799.       goto t_tccalc;
  800.     }
  801.     }
  802.  
  803.   (*_f) ^= TG_revxy;
  804.   tg_aoff = 0;
  805.   return (x);
  806. }
  807.  
  808. /* tputs() */
  809.  
  810. int
  811. tputs (register char *cp, int affcnt, int (*outc) (char))
  812.  
  813. {
  814.   register int i;
  815.   char *cpp;
  816.   int delay;
  817.  
  818. #ifdef T_DEBUG
  819.   fprintf (t_debug, "tputs(\"%s\",%d)\n", cp, affcnt);
  820. #endif
  821.  
  822.   if ((!cp) || (!outc))
  823.     return (0);
  824.  
  825.   if (isdigit (*cp))
  826.     {
  827.       delay = (int) strtol (cp, &cpp, 0);
  828.       cp = cpp;
  829.     }
  830.   else
  831. #ifdef T_DEBUG
  832.     {
  833.       cpp = cp;
  834.       delay = 0;
  835.     }
  836. #else
  837.     delay = 0;
  838. #endif
  839.  
  840.   i = *cp;
  841.  
  842.   if (i == '.')
  843.     while (isdigit (*++cp));
  844.   if (i == '*')
  845.     {
  846.       delay *= affcnt;
  847.       cp++;
  848.     }
  849.  
  850.   if (ospeed > 13)
  851.     delay <<= (ospeed - 13);
  852.   else
  853.     delay >>= (13 - ospeed);
  854.  
  855. #ifdef T_DEBUG
  856.   fprintf (t_debug, "tputs() (pad %d): %s\n", delay, cpp);
  857. #endif
  858.  
  859.   while (i = *cp++)
  860.     __funcall ((*outc), (i & 0x7f));
  861.  
  862.   if (ospeed)
  863.     while (delay-- > 0)
  864.       __funcall ((*outc), (__PC));
  865.  
  866.   return (0);
  867. }
  868.  
  869. #ifdef T_TEST
  870.  
  871. char PC, *BC, *UP;
  872.  
  873. static int out (char);
  874. static void dump (char *);
  875.  
  876. /* main() */
  877.  
  878. int
  879. main (void)
  880.  
  881. {
  882.   static char bp[1024], tbuf[512];
  883.   char *tbufp, *cm;
  884.   int rval, i;
  885.  
  886.   if ((rval = tgetent (bp, getenv ("TERM"))) < 1)
  887.     {
  888.       fprintf (stderr, "termcap: tgetent() returned %d\n", rval);
  889.       exit (1);
  890.     }
  891.  
  892.   tbufp = tbuf;
  893.  
  894.   if (tgetstr ("pc", &tbufp))
  895.     PC = *tbuf;
  896.  
  897.   if (!(BC = tgetstr ("bc", &tbufp)))
  898.     BC = "\b";
  899.  
  900.   UP = tgetstr ("up", &tbufp);
  901.  
  902.   tputs (tgetstr ("cl", &tbufp), 1, out);
  903.  
  904.   printf ("tgetent(): %s\n", bp);
  905.  
  906.   printf ("tgetflag(\"cm\"): %d\n", tgetflag ("cm"));
  907.  
  908.   printf ("tgetnum(\"li\"): %d\n", tgetnum ("li"));
  909.  
  910.   tbufp = tbuf;
  911.  
  912.   printf ("tgetstr(\"cm\"): ");
  913.   dump (cm = tgetstr ("cm", &tbufp));
  914.  
  915.   for (i = 0; i < 10; i++)
  916.     {
  917.       tputs (tgoto (cm, i << 1, i + 20), 1, out);
  918.       printf ("%d", i);
  919.     }
  920.  
  921.   printf ("\n");
  922. }
  923.  
  924. static int
  925. out (char c)
  926.  
  927. {
  928.   return (putc (c, stdout));
  929. }
  930.  
  931. static void
  932. dump (char *s)
  933.  
  934. {
  935.   if (!s)
  936.     {
  937.       printf ("(null)\n");
  938.       return;
  939.     }
  940.   while (*s)
  941.     {
  942.       if ((*s < ' ') || (*s > '\176'))
  943.     printf ("\\%03o", (int) *s);
  944.       else
  945.     putc (*s, stdout);
  946.       s++;
  947.     }
  948.   putc ('\n', stdout);
  949. }
  950.  
  951. #endif /* T_TEST */
  952.